package cn.uncode.baas.server.internal.module.user;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import cn.uncode.dal.utils.JsonUtils;
import cn.uncode.baas.server.acl.token.AccessToken;
import cn.uncode.baas.server.constant.Resource;
import cn.uncode.baas.server.dto.RestGroup;
import cn.uncode.baas.server.dto.RestRole;
import cn.uncode.baas.server.dto.RestUser;
import cn.uncode.baas.server.dto.RestUserAcl;
import cn.uncode.baas.server.exception.ValidateException;
import cn.uncode.baas.server.internal.context.RestContextManager;
import cn.uncode.baas.server.service.IResterService;
import cn.uncode.baas.server.service.IUserService;
import cn.uncode.baas.server.utils.DataUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserModule implements IUserModule {
	
	@Autowired
	IUserService userService;
	
	@Autowired
	IResterService resterService;

	@Override
	public String signup(Object param) throws ValidateException, Exception {
		Map<String, Object> map = DataUtils.convert2Map(param);
		return userService.signup(map);
	}

	@Override
	public String login(Object param) throws ValidateException, Exception {
		Map<String, Object> map = DataUtils.convert2Map(param);
		return userService.login(map);
	}

	@Override
	public int updateUser(Object param) throws ValidateException, Exception {
		Map<String, Object> map = DataUtils.convert2Map(param);
		return userService.update(map);
	}

	@Override
	public Map<String, Object> findOneUser(Object param) {
		Map<String, Object> map = DataUtils.convert2Map(param);
		if(null == map || map.size() == 0){
			AccessToken accessToken = RestContextManager.getContext().getToken();
			if(accessToken != null){
				map = new HashMap<String, Object>();
				String user = String.valueOf(RestContextManager.getContext().getToken().getAdditionalInformation().get(AccessToken.USER));
				map.put(Resource.REST_USER_USERNAME, user);
			}
		}
		return userService.getUser(map);
	}

	@Override
	public void logout(Object param) {
		Map<String, Object> map = DataUtils.convert2Map(param);
		if(null == map || map.size() == 0){
			AccessToken accessToken = RestContextManager.getContext().getToken();
			if(accessToken != null){
				map = new HashMap<String, Object>();
				map.put(Resource.REQ_ACCESS_TOKEN, RestContextManager.getContext().getToken().getValue());
			}
		}
		userService.logout(map);
	}

	@Override
	public boolean checkToken(Object param) {
		Map<String, Object> map = DataUtils.convert2Map(param);
		if(null == map || map.size() == 0){
			AccessToken accessToken = RestContextManager.getContext().getToken();
			if(accessToken != null){
				map = new HashMap<String, Object>();
				map.put(Resource.REQ_ACCESS_TOKEN, RestContextManager.getContext().getToken().getValue());
			}
		}
		return userService.checkToken(map);
	}

	@Override
	public Map<String, Object> getToken(Object param) {
		Map<String, Object> map = DataUtils.convert2Map(param);
		if(null == map || map.size() == 0){
			AccessToken accessToken = RestContextManager.getContext().getToken();
			if(accessToken != null){
				map = new HashMap<String, Object>();
				map.put(Resource.REQ_ACCESS_TOKEN, RestContextManager.getContext().getToken().getValue());
			}
		}
		return userService.getToken(map);
	}


	@Override
	public boolean checkUsername(Object param) throws ValidateException {
		Map<String, Object> map = DataUtils.convert2Map(param);
		return userService.checkUsername(map);
	}

	@Override
	public List<Map<String, Object>> findUser(Object param) {
		Map<String, Object> map = DataUtils.convert2Map(param);
		return userService.selectUsers(map);
	}

	@Override
	public List<Map<String, Object>> findGroup(Object param) {
		Map<String, Object> map = DataUtils.convert2Map(param);
		String bucket = getAttribute(map, RestGroup.BUCKET);
		String names = getAttribute(map, Resource.REST_GROUP_NAMES_KEY);
		List<RestGroup> groups= resterService.loadRestGroups(bucket, names);
		List<Map<String, Object>> result = null;
		if(null != groups){
			result = new ArrayList<Map<String, Object>>();
			for(RestGroup group : groups){
				result.add((Map<String, Object>)JsonUtils.objToMap(group));
			}
		}
		return result;
	}
	
	private String getAttribute(Map<String, Object> map, String name){
		if(null != map && map.containsKey(name)){
			return String.valueOf(map.get(name));
		}
		return null;
	}

	@Override
	public Map<String, Object> findOneGroup(Object param) {
		Map<String, Object> map = DataUtils.convert2Map(param);
		String bucket = getAttribute(map, RestGroup.BUCKET);
		String name = getAttribute(map, RestGroup.NAME);
		RestGroup group= resterService.loadRestGroup(bucket, name);
		Map<String, Object> result = null;
		if(null != group){
			result = (Map<String, Object>) JsonUtils.objToMap(group);
		}
		return result;
	}

	@Override
	public int insertGroup(Object param) throws ValidateException, Exception {
		Map<String, Object> map = DataUtils.convert2Map(param);
		String bucket = getAttribute(map, RestGroup.BUCKET);
		String name = getAttribute(map, RestGroup.NAME);
		String roles = getAttribute(map, RestGroup.ROLES);
		String desc = getAttribute(map, RestGroup.DESC);
		return resterService.insertRestGroup(bucket, name, desc, roles);
	}

	@Override
	public int updateGroup(Object param) throws ValidateException, Exception {
		Map<String, Object> map = DataUtils.convert2Map(param);
		String bucket = getAttribute(map, RestGroup.BUCKET);
		String name = getAttribute(map, RestGroup.NAME);
		String roles = getAttribute(map, RestGroup.ROLES);
		String desc = getAttribute(map, RestGroup.DESC);
		return resterService.updateRestGroup(bucket, name, desc, roles);
	}

	@Override
	public int removeGroup(Object param) throws Exception {
		Map<String, Object> map = DataUtils.convert2Map(param);
		String bucket = getAttribute(map, RestGroup.BUCKET);
		String name = getAttribute(map, RestGroup.NAME);
		String id = getAttribute(map, RestGroup.ID);
		if(StringUtils.isNotEmpty(name)){
			return resterService.deleteRestGroup(bucket, name);
		}else if(StringUtils.isNotEmpty(id)){
			return resterService.deleteRestGroup(Integer.valueOf(id));
		}
		return 0;
	}

	@Override
	public List<Map<String, Object>> findRole(Object param) {
		Map<String, Object> map = DataUtils.convert2Map(param);
		String bucket = getAttribute(map, RestGroup.BUCKET);
		String names = getAttribute(map, Resource.REST_GROUP_NAMES_KEY);
		List<RestRole> roles= resterService.loadRestRoles(bucket, names);
		List<Map<String, Object>> result = null;
		if(null != roles){
			result = new ArrayList<Map<String, Object>>();
			for(RestRole role : roles){
				result.add((Map<String, Object>)JsonUtils.objToMap(role));
			}
		}
		return result;
	}

	@Override
	public Map<String, Object> findOneRole(Object param) {
		Map<String, Object> map = DataUtils.convert2Map(param);
		String bucket = getAttribute(map, RestRole.BUCKET);
		String name = getAttribute(map, RestRole.NAME);
		RestRole role= resterService.loadRestRole(bucket, name);
		Map<String, Object> result = null;
		if(null != role){
			result = (Map<String, Object>) JsonUtils.objToMap(role);
		}
		return result;
	}

	@Override
	public int insertRole(Object param) throws ValidateException, Exception {
		Map<String, Object> map = DataUtils.convert2Map(param);
		String bucket = getAttribute(map, RestRole.BUCKET);
		String name = getAttribute(map, RestRole.NAME);
		String desc = getAttribute(map, RestRole.DESC);
		return resterService.insertRestRole(bucket, name, desc);
	}

	@Override
	public int updateRole(Object param) throws ValidateException, Exception {
		Map<String, Object> map = DataUtils.convert2Map(param);
		String bucket = getAttribute(map, RestRole.BUCKET);
		String name = getAttribute(map, RestRole.NAME);
		String desc = getAttribute(map, RestRole.DESC);
		return resterService.updateRestRole(bucket, name, desc);
	}

	@Override
	public int removeRole(Object param) throws Exception {
		Map<String, Object> map = DataUtils.convert2Map(param);
		String bucket = getAttribute(map, RestRole.BUCKET);
		String name = getAttribute(map, RestRole.NAME);
		String id = getAttribute(map, RestRole.ID);
		if(StringUtils.isNotEmpty(name)){
			return resterService.deleteRestRole(bucket, name);
		}else if(StringUtils.isNotEmpty(id)){
			return resterService.deleteRestRole(Integer.valueOf(id));
		}
		return 0;
	}

	@Override
	public Map<String, Object> findOneAcl(Object param) {
		Map<String, Object> map = DataUtils.convert2Map(param);
		String bucket = getAttribute(map, RestUserAcl.BUCKET);
		String username = getAttribute(map, RestUserAcl.USER_NAME);
		RestUserAcl userAcl= resterService.loadRestUserAcl(bucket, username);
		Map<String, Object> result = null;
		if(null != userAcl){
			result = (Map<String, Object>) JsonUtils.objToMap(userAcl);
		}
		return result;
	}

	@Override
	public int insertAcl(Object param) throws ValidateException, Exception {
		Map<String, Object> map = DataUtils.convert2Map(param);
		String bucket = getAttribute(map, RestUserAcl.BUCKET);
		String username = getAttribute(map, RestUserAcl.USER_NAME);
		String groups = getAttribute(map, RestUserAcl.GROUPS);
		String roles = getAttribute(map, RestUserAcl.ROLES);
		return resterService.insertRestUserAcl(bucket, username, groups, roles);
	}

	@Override
	public int updateAcl(Object param) throws ValidateException, Exception {
		Map<String, Object> map = DataUtils.convert2Map(param);
		String bucket = getAttribute(map, RestUserAcl.BUCKET);
		String username = getAttribute(map, RestUserAcl.USER_NAME);
		String groups = getAttribute(map, RestUserAcl.GROUPS);
		String roles = getAttribute(map, RestUserAcl.ROLES);
		return resterService.updateRestUserAcl(bucket, username, groups, roles);
	}

	@Override
	public int removeAcl(Object param) throws Exception {
		Map<String, Object> map = DataUtils.convert2Map(param);
		String bucket = getAttribute(map, RestUserAcl.BUCKET);
		String username = getAttribute(map, RestUserAcl.USER_NAME);
		String id = getAttribute(map, RestUserAcl.ID);
		if(StringUtils.isNotEmpty(username)){
			return resterService.deleteRestUserAcl(bucket, username);
		}else if(StringUtils.isNotEmpty(id)){
			return resterService.deleteRestUserAcl(Integer.valueOf(id));
		}
		return 0;
	}

	@Override
	public Map<String, Object> findOneUserCFG(Object param) {
		Map<String, Object> map = DataUtils.convert2Map(param);
		String bucket = getAttribute(map, RestUserAcl.BUCKET);
		RestUser user= resterService.loadRestUser(bucket);
		Map<String, Object> result = null;
		if(null != user){
			result = (Map<String, Object>) JsonUtils.objToMap(user);
		}
		return result;
	}

	@Override
	public int insertUserCFG(Object param) throws ValidateException, Exception {
		Map<String, Object> map = DataUtils.convert2Map(param);
		String bucket = getAttribute(map, RestUser.BUCKET);
		String table = getAttribute(map, RestUser.TABLE_NAME);
		String nameField = getAttribute(map, RestUser.USERNAME_FIELD);
		String passField = getAttribute(map, RestUser.PASSWORD_FIELD);
		String statusField = getAttribute(map, RestUser.STATUS_FIELD);
		boolean emailAuth = false;
		String emailFlag = getAttribute(map, RestUser.EMAIL_AUTH);
		if(StringUtils.isNotEmpty(emailFlag)){
			emailAuth = Boolean.valueOf(emailFlag);
		}
		String emailField = getAttribute(map, RestUser.EMAIL_FIELD);
		String defaultGroup = getAttribute(map, RestUser.DEFAULT_GROUP);
		String mobileField = getAttribute(map, RestUser.MOBILE_FIELD);
		return resterService.insertRestUser(bucket, table, nameField,
				passField, statusField, emailAuth,
				defaultGroup, emailField, mobileField);
	}

	@Override
	public int updateUserCFG(Object param) throws ValidateException, Exception {
		Map<String, Object> map = DataUtils.convert2Map(param);
		String bucket = getAttribute(map, RestUser.BUCKET);
		String table = getAttribute(map, RestUser.TABLE_NAME);
		String nameField = getAttribute(map, RestUser.USERNAME_FIELD);
		String passField = getAttribute(map, RestUser.PASSWORD_FIELD);
		String statusField = getAttribute(map, RestUser.STATUS_FIELD);
		boolean emailAuth = false;
		String emailFlag = getAttribute(map, RestUser.EMAIL_AUTH);
		if(StringUtils.isNotEmpty(emailFlag)){
			emailAuth = Boolean.valueOf(emailFlag);
		}
		String emailField = getAttribute(map, RestUser.EMAIL_FIELD);
		String defaultGroup = getAttribute(map, RestUser.DEFAULT_GROUP);
		String mobileField = getAttribute(map, RestUser.MOBILE_FIELD);
		int id = 0;
		String idStr = getAttribute(map, RestUser.ID);
		if(StringUtils.isNotEmpty(idStr)){
			id = Integer.valueOf(idStr);
		}
		return resterService.updateRestUser(id, bucket, table, nameField, passField, statusField, emailAuth, defaultGroup, emailField, mobileField);
	}

}
